home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / clang / 140_01.zip / BACKUP.C < prev    next >
Text File  |  1993-06-26  |  17KB  |  895 lines

  1. /*
  2.     BACKUP is by Steve de Plater
  3.  
  4.     66 Priam St.
  5.     Chester Hill, NSW, 2162, Australia
  6.     Phone: (02) 644 4009
  7.  
  8. VERSION LIST - Most recent version first.
  9.  
  10. 04/Jul/82 Added "usage" display when  a "?" is entered
  11.       on command line or in response to drive prompt.
  12.       Bill Bolton, Software Tools    
  13.  
  14.  
  15. You may make as many copies of this programme in either
  16. source or .COM forms as you like for your own use, or for
  17. your friends, relatives, dogs, cats, mothers-in-law etc.
  18. HOWEVER if I ever hear of anyone commercially marketing
  19. this I'll come and find them and insert their heads
  20. into an S-100 slot!!!
  21.  
  22. All I ask is that because I did the original work that
  23. you leave my name where it is in the programme. After
  24. all, nobody else should get the blame for my shoddy
  25. programming!
  26.  
  27. The function of BACKUP is to copy files from one disk to
  28. another much as PIP does. The difference is that BACKUP
  29. normally will not make a copy when a filename is found on
  30. the destination disk. Therefore, if this programme is used
  31. then you can be sure that NO files will accidently be 
  32. clobbered!
  33.  
  34. BACKUP also allows the following features:
  35. (i)    many filename masks may be included together.
  36.     They must be separated only by commas, NO SPACES!
  37.     e.g. "*.com,backup.c"
  38. (ii)    The NOT wildcard is supported when used as the first
  39.     character of a filename mask.
  40.     e.g. "!*.com" would match ALL the non .COM files.
  41. (iii)    both source and destination disks may be changed
  42.     many times during a run, as prompted by BACKUP.
  43. (iv)    If required, existing files may be renamed as .BAK
  44.     and then the copy will proceed.
  45. (v)    If required, then ONLY existing files will be copied
  46.     e.g. for installing an updated copy of a compiler etc.
  47. (vi)    If required, the copy will be stopped at the first ^Z
  48.     detected.
  49. (vii)    If required, the VERIFY programme will be called
  50.     automatically, and the BACKUP parameters will be
  51.     passed to it.
  52.  
  53. CALLING PROCEDURE:
  54.  
  55. BACKUP may be called simply by typing BACKUP<cr>;
  56. however, the following parameters may be included on the
  57. CP/M command line:
  58. (i)    mask(s)    This must be the first parameter and will
  59.         control which files are copied.
  60.  
  61. ALL THE PARAMETERS WHICH FOLLOW MAY OCCUR IN ANY ORDER AT ALL
  62. WITH OR WITHOUT SPACES BETWEEN THEM.
  63.  
  64. (ii)    <d    copy FROM drive 'd'
  65. (iii)    >d    copy TO   drive 'd'
  66. (iv)    n    Don't prompt for disk changes
  67. (v)    b    If file exists rename to .BAK and then copy
  68. (vi)    v    Run VERIFY after BACKUP is finished
  69. (vii)    z    Copy only to the first CP/M EOF (^Z).
  70. (viii)    i    Inverse mode. Copy ONLY files which exist on
  71.         both source and destination disks.
  72. (ix)    d    Debug mode. Show where everything is in RAM
  73.         BACKUP configures itself to make the most of
  74.         your system.
  75. (x)    r    Remember which files have been backed up so
  76.         that subsequent runs will not repeat.
  77.         (Implies also the Check mode below.)
  78. (xi)    c    Check (only) for previous backups
  79. (xii)    p    Print out parameter settings
  80.  
  81. \*******************************************************/
  82.  
  83. #include    bdscio.h
  84.  
  85. #define        VERSION    "1.3"
  86. #define        STACKSPACE    0x1000
  87. #define        DATE    "July 5th, 1982"
  88. #define        TIME    "14:00"
  89.  
  90. #define    V_DEFAULT FALSE        /* these default values    */
  91. #define    Z_DEFAULT FALSE        /* should be changed to    */
  92. #define    N_DEFAULT FALSE        /* configure any special*/
  93. #define    B_DEFAULT FALSE        /* BACKUP for any    */
  94. #define    M_DEFAULT FALSE        /* particular application*/
  95. #define    D_DEFAULT FALSE
  96. #define    R_DEFAULT FALSE
  97. #define C_DEFAULT FALSE
  98. #define P_DEFAULT TRUE
  99.  
  100. char    mask    [50];        /* Buffer for filename masks */
  101. char    pass_mask [50];        /* The masks passed to VERIFY*/
  102. char    work_mask [16];
  103. char    fcb1    [36];
  104. char    fn    [14];
  105. int    code;
  106. int    files;
  107. int    copies;
  108. char    *dir;            /* Where to find DIR    */
  109. char    *databuf;        /* Where to buffer stuff */
  110. unsigned stackspace;
  111. int    sectors;        /* sectors to buffer    */
  112. char    id;
  113. char    od;
  114. char    ld;
  115. char    fn1    [16];
  116. char    fn2    [16];
  117. char    fn3    [16];
  118. char    fn4    [16];
  119. char    temp    [20];
  120. char    verify;
  121. char    ctr_z;
  122. int    found_eof;
  123. int    no_wait;
  124. int    debug;
  125. int    bak;
  126. int    mode;
  127. int    remember;
  128. int    check;
  129. int    parm;
  130. int    no_bak;
  131. int    read_only;
  132. int    system;
  133. int    bak_flag;
  134. int    not_mask;
  135. char    mask2    [36];
  136. int    masks;
  137. int    matched;
  138. int    total_matched;
  139. int    total_copied;
  140. int    no_questions;
  141.  
  142.  
  143. main (argc,argv)
  144. char    **argv;
  145.  
  146. {
  147.     int    x;
  148.     int    p,z;
  149.     char    *y;
  150.  
  151.     
  152.     y = 0x501;    *y = 0x20;    /* modifies fn
  153.                      'legfc' in RTP */
  154.     stackspace = STACKSPACE;    /* configure    */
  155.     dir = endext ();        /* the RAM    */
  156.  
  157.     printf ("\nBACKUP, Ver %s, ",VERSION);
  158.     printf ("%s, by Steve de Plater\n\n",DATE);
  159.  
  160.     verify   = V_DEFAULT;
  161.     ctr_z    = Z_DEFAULT;
  162.     no_wait  = N_DEFAULT;
  163.     bak      = B_DEFAULT;
  164.     mode     = M_DEFAULT;
  165.     debug    = D_DEFAULT;
  166.     remember = R_DEFAULT;
  167.     check    = C_DEFAULT;
  168.     parm     = P_DEFAULT;
  169.  
  170.     getclp (argc,argv,&id,&od,
  171.         &verify,&ctr_z,&no_wait,&bak,&mode,&debug,
  172.         &remember,&check,&parm);
  173.  
  174.     if (remember)
  175.         check = TRUE;
  176.  
  177.     if (parm){
  178.         printf ("Parameter flag settings for this run are:\n");
  179.         printflg ("(i)    Run Verify   :",verify);
  180.         printflg ("(ii)   Stop on ^Z   :",ctr_z);
  181.         printflg ("(iii)  No-Waiting   :",no_wait);
  182.         printflg ("(iv)   Backup file  :",bak);
  183.         printflg ("(v)    Inverse mode :",mode);
  184.         printflg ("(vi)   Debug mode   :",debug);
  185.         printflg ("(vii)  Remember     :",remember);
  186.         printflg ("(viii) Check prev.  :",check);
  187.           putch ('\n');
  188.     }
  189.  
  190.     if (argc < 2)
  191.         getmask ();
  192.     else
  193.         strcpy (mask,argv[1]);
  194.         strcpy (pass_mask,mask);
  195.  
  196.     ld=bdos(25) + 'A';
  197.  
  198.     matched = copies = total_matched = total_copied = 0;
  199.     no_questions = TRUE;
  200.     do_it ();
  201.  
  202. }
  203.  
  204. getmask ()
  205.  
  206. {
  207.     int    x;
  208.  
  209.     printf ("Which files?       ");
  210.     gets (mask);
  211.     for (x=0; *(mask+x); x++)
  212.         *(mask+x) = toupper (*(mask+x));
  213.     no_questions = FALSE;
  214. }
  215.  
  216. getdir (fcb)
  217. char    *fcb;
  218.  
  219. {
  220.     int    x,y,z;
  221.     char    *s;
  222.  
  223.     y=files<<4;
  224.     s=0x80+(code<<5);
  225.     if (*(s+12))
  226.         return;
  227.     files++;
  228.     for (x=0; x<16; x++){
  229.          dir[y]=*(s+x);
  230.         y++;
  231.     }
  232. }
  233.  
  234. match_mask (s)
  235. char    *s;
  236.  
  237. {
  238.     int    x,y;
  239.  
  240.     y=TRUE;
  241.     for (x=1; x<12; x++){
  242.           if (((*(s+x)&0x7f) != mask2[x]) &&
  243.               (mask2[x]         != '?'    )){
  244.                 y=FALSE;
  245.         }
  246.     }
  247.     if (not_mask)
  248.         return !y;
  249.     else
  250.         return y;
  251. }
  252.  
  253. does_exist (s)
  254. char    *s;
  255.  
  256. {
  257.     char    fcb [36];
  258.  
  259.     setfcb (fcb,s);
  260.     if (bdos (17,fcb) > 3)
  261.         return FALSE;
  262.     else
  263.         return TRUE;
  264. }
  265.  
  266. copy (s1,s2)
  267. char    *s1,*s2;
  268.  
  269. {
  270.     int    fd1,fd2;
  271.     int    x,y,z;
  272.     int    records;
  273.  
  274.     records=0;
  275.     if ((fd1=open (s1,0)) == ERROR){
  276.         printf (" OPEN ERROR: Can't open '%s\n",s1);
  277.         quit (1);
  278.     }
  279.  
  280.     if ((fd2=creat (s2)) == ERROR){
  281.         change_disks (s2,fd1,fd2);
  282.         return;
  283.     }
  284.  
  285.     found_eof = FALSE;
  286.  
  287.     while (TRUE){
  288.         x = read (fd1,databuf,sectors);
  289.         if (!x)
  290.         break;
  291.         if (ctr_z)
  292.             z = check_eof (databuf,x);    /* returns sector */
  293.         else                    /* which contains */
  294.             z = x;                /* ^Z           */
  295.         y = write (fd2,databuf,z);
  296.         if (y != z){
  297.             change_disks (s2,fd1,fd2);
  298.             return;
  299.         }
  300.         records+=z;
  301.         if (z < sectors)
  302.             break;
  303.         if (found_eof)
  304.             break;
  305.     }
  306.     close (fd2);
  307.     fabort (fd1);
  308.     fabort (fd2);
  309.     printf ("%4d records    ",records);
  310.     if (read_only)
  311.         printf ("R/O ");
  312.     else
  313.         printf ("    ");
  314.  
  315.     if (system)
  316.         printf ("SYS ");
  317.     else
  318.         printf ("    ");
  319.  
  320.     if (bak_flag)
  321.         printf ("BAK");
  322.     putch ('\n');
  323.     copies++;
  324. }
  325.  
  326. quit (a)
  327. int    a;
  328.  
  329. {
  330.     char    t1[5],t2[5];
  331.  
  332.     if (!a){
  333.         printf ("%d file",matched);
  334.         if (matched != 1)
  335.             putch ('s');
  336.         printf (" matched, %d copied\n",copies);
  337.     }
  338.     total_matched += matched;
  339.     matched = 0;
  340.     total_copied += copies;
  341.     copies = 0;
  342.  
  343.     if (!no_wait){
  344.         printf ("\nMore ? ");
  345.         if (toupper (getchar ()) == 'Y'){
  346.             printf ("\n\n");
  347.             getmask ();
  348.             id = od = FALSE;
  349.             do_it ();
  350.         }
  351.         printf ("\nTotal Matched %d, Total Copied %d",
  352.         total_matched,total_copied);
  353.         printf ("\nMount system disk on drive '%c'\n",ld);
  354.         printf ("  press <CR> to continue: ");
  355.         bios (3);    putch ('\n');
  356.     }
  357.  
  358.     temp[0]=ld;
  359.     temp[1]=':';
  360.     temp[2]=0;
  361.     strcat (temp,"verify.com");
  362.     if (verify)
  363.         if (does_exist (temp)){
  364.             t1[0]=id;
  365.             t2[0]=od;
  366.             t1[1]=0;
  367.             t2[1]=0;
  368.             strcpy (temp,"<");
  369.             strcat (temp,t1);
  370.             strcat (temp,">");
  371.             strcat (temp,t2);
  372.             if (ctr_z)
  373.                 strcat (temp,"Z");
  374.             if (no_wait)
  375.                 strcat (temp,"N");
  376.             if (debug)
  377.                 strcat (temp,"D");
  378.             execl ("verify",pass_mask,temp,0);
  379.     }
  380.     else
  381.             printf ("\nVERIFY.COM not on logged disk\n");
  382.     exit (0);
  383. }
  384.  
  385. trim_mask (s)
  386. char    *s;
  387.  
  388. {
  389.     char    *x;
  390.     char    t[16];
  391.  
  392.     x=s;
  393.     if (*(x+1) == ':')
  394.         x+=2;
  395.     strcpy (t,x);
  396.     strcpy (s,t);
  397. }
  398.  
  399. check_eof (s,a)
  400. int    a;
  401. char    *s;
  402.  
  403. {
  404.     int    x,y;
  405.  
  406.     y=a<<7;
  407.     for (x=0; x<y; x++)
  408.         if (*(s+x) == CPMEOF){
  409.             return ((x>>7)+1);
  410.             found_eof = TRUE;
  411.         }
  412.     return a;
  413. }
  414.  
  415. getclp (argc,argv,i,o,v,z,n,b,m,d,r,c,p)
  416. int    argc;
  417. char    **argv;
  418. char    *i;        /* source disk            */
  419. char    *o;        /* destination disk        */
  420. int    *v;        /* verify flag            */
  421. int    *z;        /* CP/M EOF (^Z) flag        */
  422. int    *n;        /* no stop for disk change flag */
  423. int    *b;        /* >> to 'file'.BAK        */
  424. int    *m;        /* mode flag, 'i' for inverse    */
  425. int    *d;        /* debug mode flag        */
  426. int    *r;        /* Remember (f4) flag        */
  427. int    *c;        /* Check the (f4) flag        */
  428. int    *p;        /* Print out Parameter settings    */
  429.  
  430. {
  431.     char    line [100];
  432.     int    x;
  433.  
  434.     *i=*o=FALSE;
  435.     if (argc<3){
  436.         if (*argv[1] == '?'){
  437.             usage();
  438.             exit(0);
  439.         }
  440.         return;
  441.     }
  442.     strcpy (line,argv[2]);
  443.     for (x=3; x<argc; x++)
  444.         strcat (line,argv[x]);
  445.     for (x=0; x<strlen(line); x++)
  446.         switch (line[x])
  447.         {
  448.         case '<': {
  449.             *i=line[x+1];
  450.             x++;
  451.             break; }
  452.         case '>': {
  453.             *o=line[x+1];
  454.             x++;
  455.             break; }
  456.             case '(': {
  457.             *i=line[x+1];
  458.             x++;
  459.             break; }
  460.             case ')': {
  461.             *o=line[x+1];
  462.             x++;
  463.             break; }
  464.             case 'V': {
  465.             *v=!(*v);
  466.             break; }
  467.             case 'Z': {
  468.             *z=!(*z);
  469.             break; }
  470.             case 'N': {
  471.             *n=!(*n);
  472.             break; }
  473.             case 'B': {
  474.             *b=!(*b);
  475.             break; }
  476.         case 'I': {
  477.             *m=!(*m);
  478.             break; }
  479.         case 'D': {
  480.             *d=!(*d);
  481.             break; }
  482.         case 'R': {
  483.             *r=!(*r);
  484.             break; }
  485.         case 'C': {
  486.             *c=!(*c);
  487.             break; }
  488.         case 'P': {
  489.             *p=!(*p);
  490.             break; }
  491.         case '?': {
  492.             usage();
  493.             exit(0); }
  494.         }
  495. }
  496.  
  497. bak_file ()
  498.  
  499. {
  500.     int    z;
  501.  
  502.     if (check)
  503.         if (marked (fn1)){
  504.             printf ("Not copying: %-14.14s - previously backed up\n",fn1);
  505.             return;
  506.         }
  507.     printf ("Copying    : %-14.14s - ",fn1);
  508.     copy (fn1,fn2);
  509.     if (read_only || system){
  510.         strcpy (fn1,fn2);
  511.         for (z=0; z<14; z++){
  512.             if (fn2[z] != '.')
  513.                 continue;
  514.             z++;
  515.             if (read_only)
  516.                 fn2[z]=fn2[z]|0x80;
  517.             z++;
  518.             if (system)
  519.                 fn2[z]=fn2[z]|0x80;
  520.          }
  521.         rename (fn1,fn2);
  522.     }
  523.     if (remember)
  524.         mark (fn1);
  525. }
  526.  
  527. cant_kill (fn)
  528. char    *fn;
  529.  
  530. {
  531.     int    x,y,z;
  532.     char    myfcb [36];
  533.     char    *dma;
  534.  
  535.     setfcb (myfcb,fn);
  536.     x = bdos (17,myfcb);
  537.     if (x>3)
  538.         return FALSE;
  539.     x=x<<5;
  540.     dma=0x80;
  541.     return *(dma+x+9)&0x80;
  542. }
  543.  
  544. bak_nor ()
  545.  
  546. {
  547.     if (does_exist (fn2)){
  548.         if ((bak) && (!no_bak)){
  549.             unlink (fn3);
  550.             rename (fn2,fn3);
  551.             bak_flag=TRUE;
  552.             bak_file ();
  553.         }
  554.         else{
  555.             printf ("File exists: %-14.14s",fn2);
  556.             if ((bak) && (no_bak))
  557.                 printf (" -      Read Only!");
  558.             putch ('\n');
  559.         }
  560.     }
  561.     else
  562.         bak_file ();
  563. }
  564.  
  565. bak_inv ()
  566.  
  567. {
  568.     if (!does_exist (fn2))
  569.         return;
  570.     if (bak && !no_bak){
  571.         unlink (fn3);
  572.         rename (fn2,fn3);
  573.         bak_flag=TRUE;
  574.     }
  575.     else{
  576.         if (cant_kill (fn2)){
  577.             printf ("FILE EXISTS: %-14.14s",fn2);
  578.             printf (" -      Read Only!\n");
  579.             return;
  580.         }
  581.         unlink (fn2);
  582.     }
  583.     bak_file ();
  584. }
  585.  
  586. block_copy (s)
  587. char    *s;
  588.  
  589. {
  590.     int    x,z,p;
  591.     char    *y;
  592.     int    block_size;
  593.  
  594.     printf ("Matching mask '%s'\n\n",s);
  595.  
  596.     block_size=0;
  597.     for (x=0; x<files; x++){
  598.         y=dir+(x<<4);
  599.         if (!match_mask (y))
  600.             continue;
  601.         if (*y == 0xe5)
  602.             continue;
  603.         *y=0xe5;
  604.         matched++;
  605.         block_size++;
  606.         for (z=0; z<20; z++)
  607.             temp[z]=NULL;
  608.  
  609.         for (z=1,p=0; z<9; z++,p++)
  610.             temp[p] = *(y+z)&0x7f;
  611.         while (temp[strlen(temp)-1]==0x20)
  612.             temp[strlen(temp)-1]=NULL;
  613.  
  614.         strcat (temp,".");
  615.         p=strlen (temp);
  616.  
  617.         for (z=9; z<12; z++,p++)
  618.             temp[p] = *(y+z)&0x7f;
  619.  
  620.         read_only = *(y+9)&0x80;
  621.         system = *(y+10)&0x80;
  622.  
  623.         fn1[0]=id;
  624.         fn2[0]=od;
  625.         fn1[1]=':';
  626.         fn2[1]=':';
  627.         fn1[2]=0;
  628.         fn2[2]=0;
  629.         strcat (fn1,temp);
  630.         strcat (fn2,temp);
  631.         strcpy (fn3,fn2);
  632.         for (z=0; z<13; z++)
  633.             if (fn3[z]=='.')
  634.                 fn3[z+1]=NULL;
  635.  
  636.             strcat (fn3,"BAK");
  637.             bak_flag=FALSE;
  638.             if (cant_kill (fn2) || cant_kill(fn3))
  639.                 no_bak=TRUE;
  640.             else
  641.                 no_bak=FALSE;
  642.  
  643.             if (!mode)
  644.                 bak_nor ();
  645.             else
  646.                 bak_inv ();
  647.     }
  648.     if (!block_size)
  649.         printf ("NO FILE\n");
  650.     printf ("\n");
  651. }
  652.  
  653. mask_num (a)
  654. int    a;
  655.  
  656. {
  657.     int    x,y,z;
  658.  
  659.     y=z=0;
  660.     for (x=0; x<16; x++)
  661.         work_mask[x] = NULL;
  662.     for (x=0; x<strlen(mask); x++){
  663.         if (mask[x] == ',')
  664.             y++;
  665.         if (y==a)
  666.             break;
  667.     }
  668.     if (x >= strlen(mask))
  669.         return;
  670.     if (x)
  671.         x++;
  672.     for (y=x; y<strlen(mask); y++,z++){
  673.         if (mask[y] == ',')
  674.             break;
  675.         work_mask[z] = mask[y];
  676.     }
  677.     trim_mask (work_mask);
  678.     if (work_mask[0]=='!'){
  679.         for (x=0; x<13; x++)
  680.             work_mask[x]=work_mask[x+1];
  681.         not_mask=TRUE;
  682.     }
  683.     else
  684.         not_mask=FALSE;
  685.     setfcb (mask2,work_mask);    
  686. }
  687.  
  688. do_it ()
  689.  
  690. {
  691.     int    x,p,z;
  692.     char    *y;
  693.  
  694.     if (!id){
  695.         printf ("Source Drive:      ");
  696.         id = toupper (bios (3));
  697.         if (id != '\r')
  698.             if (id == '?'){
  699.                 printf("\n\n");
  700.                 usage();
  701.                 exit(0);
  702.             }
  703.             putch (id);
  704.         putch ('\n');
  705.         no_questions = FALSE;
  706.     }
  707.  
  708.     if (!od){
  709.         printf ("Destination Drive: ");
  710.         od = toupper (bios (3));
  711.         if (od != '\r')
  712.             if (od == '?'){
  713.                 printf("\n\n");
  714.                 usage();
  715.                 exit(0);
  716.             }
  717.             putch (od);
  718.         putch ('\n');
  719.         no_questions = FALSE;
  720.     }
  721.  
  722.     if (id == '\r')
  723.         id=ld;
  724.     if (od == '\r')
  725.         od=ld;
  726.     if (id == od){
  727.         printf ("\nINPUT & OUTPUT DRIVES MUST DIFFER!\n");
  728.         exit (1);
  729.     }
  730.     if ((id < 'A') || (id > 'P') ||
  731.         (od < 'A') || (od > 'P')){
  732.         printf ("\nINVALID DRIVE NAME!\n");
  733.         exit (1);
  734.     }
  735.  
  736.     if (!no_questions)
  737.         printf ("\n");
  738.  
  739.     if (!no_wait){
  740.         printf ("Mount disks, <CR> to continue: ");
  741.         bios (3);
  742.         printf ("\n\n");
  743.         bdos (13);
  744.     }
  745.  
  746.     files = 0;
  747.     temp[0]=id;
  748.     temp[1]=':';
  749.     temp[2]=0;
  750.     strcat (temp,"*.*");
  751.     setfcb (fcb1,temp);
  752.  
  753.     code = bdos (17,fcb1);    /* search for first    */
  754.     if (code > 3){
  755.         printf ("NO FILE\n");
  756.         quit (1);
  757.     }
  758.     getdir (fcb1);
  759.     while (TRUE){
  760.         code = bdos (18);
  761.         if (code > 3)
  762.             break;
  763.         getdir (fcb1);
  764.     }
  765.  
  766.  
  767.     config2();
  768.     masks=0;
  769.     mask_num (0);
  770.     while (strlen(work_mask)){
  771.         block_copy (work_mask);
  772.         masks++;
  773.         mask_num (masks);
  774.     }
  775.     quit (0);
  776. }
  777.  
  778. config2()
  779.  
  780. {
  781.     unsigned    x,p,z;
  782.     char        *y,*top;
  783.  
  784.     top = (topofmem() - stackspace) & 0xff00;
  785.     x = 16*files;
  786.     p = (dir + x + 0x101);
  787.     databuf = p & 0xff00;
  788.     sectors = (top - databuf) >> 7;
  789.  
  790.     if (sectors < 8){
  791.         printf ("NOT ENOUGH RAM TO RUN THIS PROGRAMME\n");
  792.         quit (1);
  793.     }
  794.     if (debug){
  795.         printf ("Compiled on %s, at %s\n\n",DATE,TIME);
  796.         printf ("Directory assigned at: %04x\n",dir);
  797.         printf ("Entries found:         %4d\n", files);
  798.         printf ("Buffer assigned at:    %04x\n",databuf);
  799.         printf ("Max. Records buffered: %4d\n", sectors);
  800.         printf ("Stackspace Reserved:   %04x\n",stackspace);
  801.         printf ("Top of Buffer at:      %04x\n\n",top);
  802.     }
  803. }
  804.  
  805. marked (s)
  806. char    *s;
  807.  
  808. {
  809.     char    fcb [36];
  810.     int    c;
  811.     char    *p;
  812.  
  813.     setfcb (fcb,s);
  814.     c = bdos (17,fcb);
  815.     p = 0x80 + 32*c + 4;
  816.     if ((*p) & 0x80)
  817.         return TRUE;
  818.     else
  819.         return FALSE;
  820. }
  821.  
  822. mark (s)
  823. char    *s;
  824.  
  825. {
  826.     char    fcb [36];
  827.  
  828.     setfcb (fcb,s);
  829.     fcb[4] = fcb[4] | 0x80;
  830.     bdos (30,fcb);
  831. }
  832.  
  833. change_disks (s2,fd1,fd2)
  834. char    *s2;
  835. int    fd1;
  836. int    fd2;
  837.  
  838. {
  839.     char    fcb [36];
  840.     int    x;
  841.  
  842.     setfcb (fcb,s2);
  843.     for (x=1; x<13; x++)
  844.         fcb[x]=fcb[x]&0x7f;
  845.     bdos (30,fcb);    /* reset flags (R/O etc), and    */
  846.     bdos (19,fcb);    /* delete incomplete copy    */
  847.     fabort (fd1);    /* and free up the fds in    */
  848.     fabort (fd2);    /* the rtp            */
  849.  
  850.     printf ("DESTINATION DISK IS FULL,\n\n");
  851.     printf ("  Change disk on drive '%c',\n",od);
  852.     printf ("  press <CR> to continue: ");
  853.     bios (3);
  854.     printf ("\n\n");
  855.  
  856.     bdos (13);
  857.     if (!mode)        /* check inverse mode        */
  858.         bak_nor ();    /* and try again        */
  859.     else
  860.         bak_inv ();
  861. }
  862.  
  863. printflg (s,a)
  864. char    *s;
  865. int    a;
  866.  
  867. {
  868.     printf ("  %s ",s);
  869.     if (a)
  870.         printf ("ON\n");
  871.     else
  872.         printf ("OFF\n");
  873. }
  874.  
  875. usage()
  876.  
  877. {
  878.     printf("Usage : \t BACKUP parameters\n\n");
  879.     printf("Where valid parameters are:\n\n");
  880.     printf("(i)\tmask(s)\tThis must be the first parameter and will\n");
  881.     printf("\t\tcontrol which files are copied.\n\n");
  882.     printf("ALL THE PARAMETERS WHICH FOLLOW MAY OCCUR IN ANY ORDER\n\n");
  883.     printf("(ii)\t<d\tcopy FROM drive 'd'\n");
  884.     printf("(iii)\t>d\tcopy TO   drive 'd'\n");
  885.     printf("(iv)\tn\tDon't prompt for disk changes\n");
  886.     printf("(v)\tb\tIf file exists rename to .BAK and then copy\n");
  887.     printf("(vi)\tv\tRun VERIFY after BACKUP is finished\n");
  888.     printf("(vii)\tz\tCopy only to the first CP/M EOF (^Z).\n");
  889.     printf("(viii)\ti\tCopy ONLY files which exist on source and dest\n");
  890.     printf("(ix)\td\tDebug mode. Show where everything is in RAM\n");
  891.     printf("(x)\tr\tTag files as they are backed up\n");
  892.     printf("(xi)\tc\tCheck (only) for previous backups\n");
  893.     printf("(xii)\tp\tPrint out parameter settings\n");
  894. }
  895.